﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Server;
using ChatData;
namespace Client
{
    /// <summary>
    /// This is the base control for MessageBase items
    /// </summary>
    public partial class EntryList : UserControl
    {
        TimeStream<Post> myfeed = new TimeStream<Post>();
        TimeStream<FilePost>myfiles = new TimeStream<FilePost>();
        TimeStream<DMPost> myDMS = new TimeStream<DMPost>();

        public event PostEventhandler PostEvent;
        public event DMPostEventhandler DMPostEvent;
        public event FileEventhandler FileForwardEvent;
        public event FileReplyEventhandler FileReplyEvent;
        public event FileSaveEventhandler FileSaveEvent;
        public event StatusChangedEventhandler StatusChangeEvent;
        delegate void SetResetCallback(ControlSortedList thedic);

        public String Username{ get; set; }
        public String  Status { get; set; }
        public EntryList()
        {
            InitializeComponent();
            this.Dock = DockStyle.Fill;
            setEvents();
            this.buttonSpecHeaderGroup2.Image = global::Client.Properties.Resources.arrow_back_16Grey;
            this.Status = "Not Logged in";
            this.HeaderGroup.ValuesSecondary.Description = this.Status;
        }
        /// <summary>
        ///  Intialise a new EntryList with a new item feed
        /// </summary>
        public EntryList(List<Post> newfeed)
        {
            InitializeComponent();
            myfeed.AddRange(newfeed);
            this.Dock = DockStyle.Fill;
            Reset();
            setEvents();
            this.buttonSpecHeaderGroup2.Image = global::Client.Properties.Resources.arrow_back_16Grey;
            this.Status = "Not Logged in";
            this.HeaderGroup.ValuesSecondary.Description = this.Status;
            this.ScrollControlIntoView(this.Controls[this.Controls.Count]);
        }
        /// <summary>
        ///  This function sets up events handlers for the Status menu items
        /// </summary>
        private void setEvents()
        {
            this.kryptonContextMenuItem1.Click += new EventHandler(kryptonContextMenuItem1_Click);
            this.kryptonContextMenuItem2.Click += new EventHandler(kryptonContextMenuItem2_Click);
            this.kryptonContextMenuItem3.Click += new EventHandler(kryptonContextMenuItem3_Click);
            this.kryptonContextMenuItem4.Click += new EventHandler(kryptonContextMenuItem4_Click);
        }
        /// <summary>
        ///  Set the logged in user. String user - the username of the current user
        /// </summary>
        public void LoggedIn(string user)
        {
            this.Username = user;
            this.HeaderGroup.ValuesPrimary.Description = this.Username;
            this.buttonSpecHeaderGroup2.Image = global::Client.Properties.Resources.arrow_back_16Green;
            this.Status = "Avaliable";
            this.HeaderGroup.ValuesSecondary.Description = this.Status;
        }
        /// <summary>
        /// Disply a message in the Secondary header
        /// </summary>
        public void DisplayMessage(string message)
        {
            this.HeaderGroup.ValuesSecondary.Heading = message;
        }
        /// <summary>
        ///  The the file path. Returns string
        /// </summary>
        private string getFile()
        {
            System.Windows.Forms.DialogResult result = this.folderBrowserDialog1.ShowDialog();

            if (result == DialogResult.OK)
            {
                string file = this.folderBrowserDialog1.SelectedPath;
                return file;
            }
            return "";
        }
        #region Feeds
        /// <summary>
        ///  Update the display with NEW items. 
        /// </summary>
        public void addPostFeed(List<Post> newfeed, List<DMPost> newDMS)
        {
            
            ControlSortedList thedic = new ControlSortedList();
            foreach (Post item in newfeed)
            {
                Message temp = new Message(item);
                temp.Reply+=new PostReplyEventhandler(temp_Reply);
                thedic.Add(item.Time, temp);
            }
            foreach (DMPost item in newDMS)
            {
                DMMessage temp = new DMMessage(item);
                temp.Reply +=new DMPostEventhandler(temp_Reply);
                thedic.Add(item.Time, temp);
            }
            myfeed.AddRange(newfeed);
            this.myDMS.AddRange(newDMS);
            Reset(thedic);
        }
        /// <summary>
        ///  Update the Display with new POST items
        /// </summary>
        public void addPostFeed(List<Post> newfeed)
        {
            myfeed.AddRange(newfeed);
            ControlSortedList thedic = new ControlSortedList();
            foreach (Post item in myfeed)
            {
                Message temp = new Message(item);
                temp.Reply += new PostReplyEventhandler(temp_Reply);
                thedic.Add(item.Time, temp);
            }
            Reset(thedic);
        }
        /// <summary>
        ///  Update the Display with NEW DMPost items
        /// </summary>
        public void addDmFeed(List<DMPost> newDMS)
        {

            this.myDMS.AddRange(newDMS);
            ControlSortedList thedic = new ControlSortedList();
            foreach (DMPost item in myDMS)
            {
                DMMessage temp = new DMMessage(item);
                temp.Reply += new DMPostEventhandler(temp_Reply);
                thedic.Add(item.Time,temp);
            }
            Reset(thedic);
        }

        /// <summary>
        ///  Add  a file. There is no stream for files. Files are added one by one
        /// </summary>
        public void addFile(FilePost newFile)
        {
            this.myfiles.Add(newFile);

            ControlSortedList thedic = new ControlSortedList();

                FileMessage temp = new FileMessage(newFile);
                temp.Save += new SaveEventhandler(temp_Save);
                temp.Forward += new ForwardEventHandler(temp_Forward);
                temp.Reply+=new FileReplyEventhandler(temp_Reply);
                thedic.Add(newFile.Time, temp);

            Reset(thedic);
        }
        #endregion

        #region Reset
        /// <summary>
        ///  Add the ControlSortedList to the Display
        /// </summary>
        private void Reset(ControlSortedList thedic )
        {
            if (HeaderGroup.InvokeRequired)
            {
                SetResetCallback call = new SetResetCallback(this.Reset);
                HeaderGroup.Invoke(call, thedic);
            }
            else{
                this.SuspendLayout();
                foreach (KeyValuePair<DateTime, Control> item in thedic)
                {
                    HeaderGroup.Panel.Controls.Add(item.Value);
                }
                this.HeaderGroup.ValuesSecondary.Heading = "";
                this.ResumeLayout();
            }
        }
        /// <summary>
        //Display items already added to the list.
        /// </summary>
        private void Reset()
        {
            this.SuspendLayout();
            ControlSortedList thedic = new ControlSortedList();
            foreach(Post item in myfeed)
            {
                Message temp = new Message(item);
                temp.Reply += new PostReplyEventhandler(temp_Reply);
                thedic.Add(item.Time,temp);
            }
            foreach(DMPost item in myDMS)
            {
                DMMessage temp = new DMMessage(item);
                temp.Reply+=new DMPostEventhandler(temp_Reply);
                thedic.Add(item.Time, temp);
            }
            foreach (FilePost item in myfiles)
            {
                FileMessage temp = new FileMessage(item);
                temp.Save +=new SaveEventhandler(temp_Save);
                temp.Forward += new ForwardEventHandler(temp_Forward);
                temp.Reply +=new FileReplyEventhandler(temp_Reply);
                thedic.Add(item.Time, temp);
            }
            foreach (KeyValuePair<DateTime, Control> item in thedic)
            {
                HeaderGroup.Panel.Controls.Add(item.Value);
            }
            this.HeaderGroup.ValuesSecondary.Heading = "";
            this.ResumeLayout();
        }
        #endregion

        //these events serve as repeaters for Message events
        #region OnEvent
        /// <summary>
        /// Repeaded Post event from Edit
        /// </summary>
        protected void OnPost(DataEventArgs<Post> e)
        {
            PostEvent(this, e);
        }
        /// <summary>
        /// Repeaded DM event from Edit
        /// </summary>
        protected void OnDM(ReplyChatEventArgs<DMPost>e)
        {
            DMPostEvent(this, e);
        }
        /// <summary>
        /// Repeaded File event from Edit
        /// </summary>
        protected void OnFile(DataEventArgs<FilePost> e)
        {
            FileForwardEvent(this, e);
        }
        /// <summary>
        /// Repeaded File Reply event from Edit
        /// </summary>
        protected void OnFileReply(ReplyChatEventArgs<FilePost> e)
        {
            FileReplyEvent(this, e);
        }
        /// <summary>
        /// Repeaded File Save event from Edit
        /// </summary>
        protected void OnFileSave (FileSaveEventArgs<FilePost> e)
        {
            FileSaveEvent(this, e);
        }
        /// <summary>
        ///Status Changed
        /// </summary>
        protected void OnStatus(DataEventArgs<String> e)
        {
            StatusChangeEvent(this, e);
        }
        #endregion

        // OnEvents handlers repeat the events for Clientbase
        #region MessagePost Events
        /// <summary>
        /// Message Reply event
        /// </summary>
        void temp_Reply(object sender, ReplyChatEventArgs<Post> e)
        {
            OnPost(new DataEventArgs<Post>(e.Data, EventType.Reply ));
        }
        #endregion
        # region DmPost Events
        /// <summary>
        /// DM Reply event
        /// </summary>
        void temp_Reply(object sender, ReplyChatEventArgs<DMPost> e)
        {
            OnDM(e);
        }
        #endregion
        #region FilePost Events
        /// <summary>
        /// FilePost Reply event
        /// </summary>
        void temp_Reply(object sender, ReplyChatEventArgs<FilePost> e)
        {
            OnFileReply(e);
        }
        /// <summary>
        /// File Forward event
        /// </summary>
        void temp_Forward(object e, ChatEventArgs<FilePost> eventargs)
        {
            OnFile(new DataEventArgs<FilePost>(eventargs.Data, EventType.Forward));
        }
        /// <summary>
        /// File Save event
        /// </summary>
        void temp_Save(object sender, ChatEventArgs<FilePost> e)
        {
            OnFileSave(new FileSaveEventArgs<FilePost>(e.Data, getFile()));
        }
        #endregion

        #region ButtonSpecs
        //Options
        /// <summary>
        /// Opens Options
        /// </summary>
        private void buttonSpecHeaderGroup1_Click_1(object sender, EventArgs e)
        {
           Options dialog = new Options();
           DialogResult result = dialog.ShowDialog();

            if(result == DialogResult.OK)
            {

            }
            
        }
        //Status
        #endregion
        #region MenuItems
        //busy
        void kryptonContextMenuItem4_Click(object sender, EventArgs e)
        {
            this.Status = "Busy";
            this.buttonSpecHeaderGroup2.Image = global::Client.Properties.Resources.arrow_back_16Red;
            this.HeaderGroup.ValuesSecondary.Description = "Busy";
            OnStatus(new DataEventArgs<string>(this.Status, EventType.Status));
        }
        //invisible
        void kryptonContextMenuItem3_Click(object sender, EventArgs e)
        {
            this.Status = "Invisible";
            this.buttonSpecHeaderGroup2.Image = global::Client.Properties.Resources.arrow_back_16Yellow;
            this.HeaderGroup.ValuesSecondary.Description = "Invisible";
            OnStatus(new DataEventArgs<string>(this.Status, EventType.Status));
        }
        //unavaliable
        void kryptonContextMenuItem2_Click(object sender, EventArgs e)
        {
            this.Status = "Unavaliable";
            this.buttonSpecHeaderGroup2.Image = global::Client.Properties.Resources.arrow_back_16Grey;
            this.HeaderGroup.ValuesSecondary.Description = "Unavaliable";
            OnStatus(new DataEventArgs<string>(this.Status, EventType.Status));
        }
        //avaliable
        void kryptonContextMenuItem1_Click(object sender, EventArgs e)
        {
            this.Status = "Avaliable";
            this.buttonSpecHeaderGroup2.Image = global::Client.Properties.Resources.arrow_back_16Green;
            this.HeaderGroup.ValuesSecondary.Description = "Avaliable";
            OnStatus(new DataEventArgs<string>(this.Status, EventType.Status));
        }
        #endregion
    }
}
